package app.gui.control
{
	import app.util.*;
	import app.util.image.calc.*;
	
	import flash.display.*;
	import flash.events.*;
	import flash.geom.*;
	
	import mx.containers.Canvas;
	import mx.controls.*;
	import mx.managers.*;
	
	public class ImageCutter
	{
		private var image:Canvas = null;
			
		private var cropX:int;
		private var cropY:int;
		private var cropWidth:int;
		private var cropHeight:int;
		
		private var dragX:int;
		private var dragY:int;	
		private var isResizing:Boolean;
		
		[Embed(source="/app/asset/resizeCursor.png")]
		private static var resizeCursor:Class;			
		
		public static const RESIZE_CORNER_SIZE:int = 10;
		public static const RESIZE_CORNER_OFFSET:int = -10;		
		
		public function install(img:Canvas):void
		{
			this.image = img;		
			this.cropWidth = this.image.width / 2;
			this.cropHeight = this.image.height / 2;
			this.cropX = this.image.width / 4;
			this.cropY = this.image.height / 4;
			this.dragX = this.dragY = int.MIN_VALUE;
			this.isResizing = false;
			
			this.image.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
			this.image.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
			this.image.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
			this.image.addEventListener(MouseEvent.ROLL_OUT, onMouseUp);	
			
			this.drawCrop();	
		}

		public function uninstall():void
		{
			if(this.image != null)
			{
				this.image.graphics.clear();
				this.image.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
				this.image.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
				this.image.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
				this.image.removeEventListener(MouseEvent.ROLL_OUT, onMouseUp);	
				this.image = null;
			}
		}
		
		public function redraw():void
		{
			if(this.image != null)
			{
				var scale:Number = 1;
				this.cropX = MathUtility.clamp(0, this.image.width - this.cropWidth, this.cropX) * scale;
				this.cropY = MathUtility.clamp(0, this.image.height - this.cropHeight, this.cropY) * scale;
				this.cropWidth = MathUtility.clamp(1, this.image.width - this.cropX, this.cropWidth) * scale;
				this.cropHeight = MathUtility.clamp(1, this.image.height - this.cropY, this.cropHeight) * scale;
				this.drawCrop();
			}
		}
		
		public function getCutterRectangle():Rectangle
		{
			if(this.image == null)
			{
				throw new Error("Not in cut-mode");
			}
			var scale:Number = Mediator.getCurrentImageConfig().scale;
			return new Rectangle(this.cropX / scale, 
							this.cropY / scale, 
							this.cropWidth / scale,
							this.cropHeight / scale);
		}
		
		private function drawCrop():void
		{
			var g:Graphics = this.image.graphics;

			//Draw crop border
			g.clear();
			g.lineStyle(2, 0, 1);
			g.drawRect(this.cropX, this.cropY, this.cropWidth, this.cropHeight);
			
			//Draw un-crop region with alpha
			g.lineStyle(0, 0, 0);
			g.beginFill(0xffffff, 0.3);
			g.drawRect(0, 0, this.image.width, this.cropY);
			g.drawRect(0, this.cropY, this.cropX, this.cropHeight);
			g.drawRect(this.cropX + this.cropWidth, this.cropY, 
				this.image.width - this.cropX - this.cropWidth, this.cropHeight);
			g.drawRect(0, this.cropY + this.cropHeight, 
				this.image.width, this.image.height - this.cropY - this.cropHeight);
			g.endFill(); 
		}
		
		private function onMouseDown(e:MouseEvent):void
		{
			var cropRect:Rectangle = new Rectangle(this.cropX, this.cropY, 
				this.cropWidth, this.cropHeight);
			var resizeRect:Rectangle = new Rectangle(
				this.cropX + this.cropWidth - RESIZE_CORNER_SIZE,
				this.cropY + this.cropHeight - RESIZE_CORNER_SIZE,
				RESIZE_CORNER_SIZE, RESIZE_CORNER_SIZE);
				
			if(resizeRect.contains(e.localX, e.localY))
			{	
				this.dragX = e.localX;
				this.dragY = e.localY;
				this.isResizing = true;					
			}
			else if(cropRect.contains(e.localX, e.localY))
			{
				this.dragX = e.localX;
				this.dragY = e.localY;	
				this.isResizing = false;
			}			
		}
		
		private function onMouseMove(e:MouseEvent):void
		{			
			//Check resize
			var resizeRect:Rectangle = new Rectangle(
				this.cropX + this.cropWidth - RESIZE_CORNER_SIZE,
				this.cropY + this.cropHeight - RESIZE_CORNER_SIZE,
				RESIZE_CORNER_SIZE, RESIZE_CORNER_SIZE);
			if(resizeRect.contains(e.localX, e.localY))
			{
				CursorManager.removeCursor(CursorManager.currentCursorID);
				CursorManager.setCursor(resizeCursor, 2, RESIZE_CORNER_OFFSET, RESIZE_CORNER_OFFSET);
			}
			else 
			{
				CursorManager.removeCursor(CursorManager.currentCursorID);
			}
			
			//Check drag
			if(this.dragX != int.MIN_VALUE)
			{
				if(this.isResizing)
				{
					this.cropWidth += (e.localX - this.dragX);
					this.cropHeight += (e.localY - this.dragY);
						
					this.cropWidth = MathUtility.clamp(1, this.image.width - this.cropX, this.cropWidth);
					this.cropHeight = MathUtility.clamp(1, this.image.height - this.cropY, this.cropHeight);
				}
				else 
				{
					this.cropX += (e.localX - this.dragX);
					this.cropY += (e.localY - this.dragY);
						
					this.cropX = MathUtility.clamp(0, this.image.width - this.cropWidth, this.cropX);
					this.cropY = MathUtility.clamp(0, this.image.height - this.cropHeight, this.cropY);
				}
				
				this.drawCrop();

				this.dragX = e.localX;
				this.dragY = e.localY;
			}	
		}
		
		private function onMouseUp(e:MouseEvent):void
		{
			this.dragX = int.MIN_VALUE;
			this.isResizing = false;
		}	
	}
}